package com.hww.common.util;

import android.graphics.drawable.Drawable;

import androidx.annotation.DrawableRes;
import androidx.annotation.RawRes;
import androidx.core.content.ContextCompat;

import com.hww.common.MyAppThis;

import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.util.Collections;
import java.util.List;

/**
 * desc  : 资源工具类，用于获取应用中的各种资源。
 */
public final class ResourceUtils {

    /*定义缓冲区大小常量*/
    private static final int BUFFER_SIZE = 8192;

    private ResourceUtils() {
        throw new UnsupportedOperationException("u can't instantiate me...");
    }

    /**
     * 根据资源ID返回Drawable对象。
     *
     * @param id 资源的ID。
     * @return 返回与ID对应的Drawable对象。
     */
    public static Drawable getDrawable(@DrawableRes int id) {
        return ContextCompat.getDrawable(MyAppThis.getThis(), id);
    }

    /**
     * 根据名称获取ID资源的标识符。
     *
     * @param name ID资源的名称。
     * @return 返回ID资源的标识符。
     */
    public static int getIdByName(String name) {
        return MyAppThis.getThis().getResources().getIdentifier(name, "id", MyAppThis.getThis().getPackageName());
    }

    /**
     * 根据名称获取字符串资源的标识符。
     *
     * @param name 字符串资源的名称。
     * @return 返回字符串资源的标识符。
     */
    public static int getStringIdByName(String name) {
        return MyAppThis.getThis().getResources().getIdentifier(name, "string", MyAppThis.getThis().getPackageName());
    }

    /**
     * 根据名称获取颜色资源的标识符
     *
     * @param name 颜色资源帝饿名称.
     * @return 返回颜色的标识符。
     */
    public static int getColorIdByName(String name) {
        return MyAppThis.getThis().getResources().getIdentifier(name, "color", MyAppThis.getThis().getPackageName());
    }

    /**
     * 根据名称获取尺寸资源的标识符
     *
     * @param name 尺寸资源的名称.
     * @return 返回尺寸资源的标识符
     */
    public static int getDimenIdByName(String name) {
        return MyAppThis.getThis().getResources().getIdentifier(name, "dimen", MyAppThis.getThis().getPackageName());
    }

    /**
     * 根据名称获取Drawable资源的标识符
     *
     * @param name Drawable资源的名称.
     * @return 返回Drawable资源的标识符
     */
    public static int getDrawableIdByName(String name) {
        return MyAppThis.getThis().getResources().getIdentifier(name, "drawable", MyAppThis.getThis().getPackageName());
    }

    /**
     * 根据名称获取Mipmap资源的标识符
     *
     * @param name Mipmap资源的名称.
     * @return 返回Mipmap资源的标识符
     */
    public static int getMipmapIdByName(String name) {
        return MyAppThis.getThis().getResources().getIdentifier(name, "mipmap", MyAppThis.getThis().getPackageName());
    }

    /**
     * 根据名称获取Layout布局资源的标识符
     *
     * @param name Layout布局资源的名称.
     * @return 返回布局资源的标识符
     */
    public static int getLayoutIdByName(String name) {
        return MyAppThis.getThis().getResources().getIdentifier(name, "layout", MyAppThis.getThis().getPackageName());
    }

    /**
     * 根据名称获取Style资源的标识符
     *
     * @param name 样式的名称.
     * @return 根据名称获取到的样式资源的标识符
     */
    public static int getStyleIdByName(String name) {
        return MyAppThis.getThis().getResources().getIdentifier(name, "style", MyAppThis.getThis().getPackageName());
    }

    /**
     * 根据名称返回动画资源的标识符
     *
     * @param name 动画的名称.
     * @return 返回动画资源的标识符
     */
    public static int getAnimIdByName(String name) {
        return MyAppThis.getThis().getResources().getIdentifier(name, "anim", MyAppThis.getThis().getPackageName());
    }

    /**
     * 根据名称返回Menu资源的标识符
     *
     * @param name Menu资源的名称.
     * @return 返回Menu资源的标识符
     */
    public static int getMenuIdByName(String name) {
        return MyAppThis.getThis().getResources().getIdentifier(name, "menu", MyAppThis.getThis().getPackageName());
    }

    /**
     * 拷贝assets目录下的文件到设备下指定的目录
     *
     * @param assetsFilePath assets文件夹的路径.
     * @param destFilePath   目标文件的路径.
     * @return {@code true}: 拷贝成功<br>{@code false}: 拷贝失败
     */
    public static boolean copyFileFromAssets(final String assetsFilePath, final String destFilePath) {
        boolean res = true;
        try {
            String[] assets = MyAppThis.getThis().getAssets().list(assetsFilePath);
            if (assets != null && assets.length > 0) {
                for (String asset : assets) {
                    res &= copyFileFromAssets(assetsFilePath + "/" + asset, destFilePath + "/" + asset);
                }
            } else {
                res = FileIOUtils.writeFileFromIS(
                        destFilePath,
                        MyAppThis.getThis().getAssets().open(assetsFilePath)
                );
            }
        } catch (IOException e) {
            e.printStackTrace();
            res = false;
        }
        return res;
    }

    /**
     * 将assets文件夹中的内容读取为字符串
     *
     * @param assetsFilePath assets文件夹中文件的路径.
     * @return 返回文件中内容的字符串
     */
    public static String readAssets2String(final String assetsFilePath) {
        return readAssets2String(assetsFilePath, null);
    }

    /**
     * 读取assets文件夹中的内容，并制定字符集
     *
     * @param assetsFilePath assets文件夹中文件的路径.
     * @param charsetName    字符集类型的名称.
     * @return 返回文件的内容
     */
    public static String readAssets2String(final String assetsFilePath, final String charsetName) {
        try {
            InputStream is = MyAppThis.getThis().getAssets().open(assetsFilePath);
            byte[] bytes = ConvertUtils.inputStream2Bytes(is);
            if (bytes == null) return "";
            if (StringUtils.isSpace(charsetName)) {
                return new String(bytes);
            } else {
                try {
                    return new String(bytes, charsetName);
                } catch (UnsupportedEncodingException e) {
                    e.printStackTrace();
                    return "";
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
            return "";
        }
    }

    /**
     * 读取assets文件夹中的内容，转换为列表
     *
     * @param assetsPath assets文件夹中文件的路径.
     * @return 返回文件的内容
     */
    public static List<String> readAssets2List(final String assetsPath) {
        return readAssets2List(assetsPath, "");
    }

    /**
     * 读取assets文件夹中的内容，转换为列表
     *
     * @param assetsPath  assets文件夹中文件的路径.
     * @param charsetName 字符集类型的名称.
     * @return 返回文件的内容作为别表
     */
    public static List<String> readAssets2List(final String assetsPath,
                                               final String charsetName) {
        try {
            return ConvertUtils.inputStream2Lines(MyAppThis.getThis().getResources().getAssets().open(assetsPath), charsetName);
        } catch (IOException e) {
            e.printStackTrace();
            return Collections.emptyList();
        }
    }


    /**
     * 从raw文件夹中复制文件到指定路径
     *
     * @param resId        资源ID.
     * @param destFilePath 目标文件路径.
     * @return {@code true}: 拷贝成功<br>{@code false}: 拷贝失败
     */
    public static boolean copyFileFromRaw(@RawRes final int resId, final String destFilePath) {
        return FileIOUtils.writeFileFromIS(
                destFilePath,
                MyAppThis.getThis().getResources().openRawResource(resId)
        );
    }

    /**
     * 将raw资源中的内容读取为字符串
     *
     * @param resId 资源ID.
     * @return the content of resource in raw
     */
    public static String readRaw2String(@RawRes final int resId) {
        return readRaw2String(resId, null);
    }

    /**
     * 将raw资源文件内容读取为字符串
     *
     * @param resId       资源ID，用于标识需要读取的资源文件.
     * @param charsetName 字符集名称.
     * @return 返回资源文件的内容作为字符串
     */
    public static String readRaw2String(@RawRes final int resId, final String charsetName) {
        InputStream is = MyAppThis.getThis().getResources().openRawResource(resId);
        byte[] bytes = ConvertUtils.inputStream2Bytes(is);
        if (bytes == null) return null;
        if (StringUtils.isSpace(charsetName)) {
            return new String(bytes);
        } else {
            try {
                return new String(bytes, charsetName);
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
                return "";
            }
        }
    }

    /**
     * 将RAW资源文件内容读取为字符串列表
     *
     * @param resId 资源ID.
     * @return the content of file in assets
     */
    public static List<String> readRaw2List(@RawRes final int resId) {
        return readRaw2List(resId, "");
    }

    /**
     * 将RAW资源文件内容读取为字符串列表
     *
     * @param resId       资源ID.
     * @param charsetName 字符集名称.
     * @return 返回资源文件的内容
     */
    public static List<String> readRaw2List(@RawRes final int resId,
                                            final String charsetName) {
        return ConvertUtils.inputStream2Lines(MyAppThis.getThis().getResources().openRawResource(resId), charsetName);
    }
}
